package algo3c3g7.mvc;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;

import algo3c3g7.funciones.Funcion;
import algo3c3g7.funciones.FuncionesFactory;
import algo3c3g7.parser.GeneradorDeFunciones;
import algo3c3g7.parser.Parseador;

public class ControladorCreacionFuncion extends Observable {

	private VistaCreacionFuncion vistaCreacionFuncion;
	private VistaGrafico vistaGrafico;
	private ModeloFuncion modeloActual = new ModeloFuncion();
	private Parseador parseador = new Parseador();
	private GeneradorDeFunciones generador = new GeneradorDeFunciones();
	private ControladorFuncionesCargadas controladorFunciones;

	private class EscuchaBotonIntroducirFuncion implements ActionListener {

		public void actionPerformed(ActionEvent e) {

			ModeloFuncion modelo = generarFuncion();
			vistaGrafico.graficarFuncion(modelo.getFuncion());
			controladorFunciones.addFuncion(modelo);

		}

	}

	public ActionListener getListenerBotonIntroducirFuncion() {
		return new EscuchaBotonIntroducirFuncion();
	}

	private class EscuchaBotonEvaluar implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			try {
				evaluar();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}

		private void evaluar() throws Exception {
			double valor = vistaCreacionFuncion.getEvaluarEn();
			double resultado;
			resultado = modeloActual.getFuncion().evaluar(valor);
			vistaCreacionFuncion.setResultado(resultado);
			vistaCreacionFuncion.setFuncionSeleccionada(modeloActual.getExpresion());
		}

	}

	public ActionListener getListenerBotonEvaluar() {
		return new EscuchaBotonEvaluar();
	}

	private ModeloFuncion generarFuncion() {
		
		ModeloFuncion modelo =new ModeloFuncion();
		
		String expresion = vistaCreacionFuncion.getExpresionFuncionIntroducida();

		try {
			String notPostfija = parseador.parsear(expresion);

			modelo.setFuncion(generador.f(notPostfija));
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

		modelo.setGraficar(true);
		modelo.setExpresion(expresion);

		return modelo;
	}

	public void setVistaCreacionFuncion(
			VistaCreacionFuncion vistaCreacionFuncion) {
		this.vistaCreacionFuncion = vistaCreacionFuncion;
	}

	public Funcion getFuncionModelo() {

		return this.modeloActual.getFuncion();

	}

	public void notificarObservadores() {
		this.setChanged();
		this.notifyObservers();
	}

	public void setVistaGrafico(VistaGrafico vistaGrafico) {
		this.vistaGrafico = vistaGrafico;
	}

	public void setControladorFunciones(
			ControladorFuncionesCargadas controladorFunciones) {
		this.controladorFunciones = controladorFunciones;
	}
}
